package ru.papergames.model.proxies
{
	import ru.papergames.model.binsocket.SocketDataManager;
	import ru.papergames.model.binsocket.data.ExtByteArray;
	import ru.papergames.model.binsocket.events.SocketConnectionEvent;
	import ru.papergames.model.vo.MessagingConnectVO;

	public class BaseSocketProxy extends BaseProxy
	{
		
		public static const CONNECTION_SUCCESS:String = '.CONNECTION_SUCCESS';
		public static const CONNECTION_CLOSED:String = '.CONNECTION_CLOSED';
		public static const CONNECTION_ERROR:String = '.CONNECTION_ERROR';
		
		protected var sdManager:SocketDataManager = new SocketDataManager();
		
		public var connectionVO:MessagingConnectVO;
		
		public function BaseSocketProxy(pName:String, data:Object)
		{
			super(pName, data);
		}
				
		override public function onRegister():void
		{
			super.onRegister();
			
			sdManager.addEventListener(SocketConnectionEvent.SOCKET_CONNECTED, onConnect);
			sdManager.addEventListener(SocketConnectionEvent.SOCKET_CLOSED, onDisconnect);
			sdManager.addEventListener(SocketConnectionEvent.SOCKET_DATA, onSocketData);
			sdManager.addEventListener(SocketConnectionEvent.SOCKET_FAULT_DATA, onFaultData);
			sdManager.addEventListener(SocketConnectionEvent.SOCKET_ERROR, onConnError);
		}
		
		override public function onRemove():void
		{
			super.onRemove();
			
			sdManager.removeEventListener(SocketConnectionEvent.SOCKET_CONNECTED, onConnect);
			sdManager.removeEventListener(SocketConnectionEvent.SOCKET_CLOSED, onDisconnect);
			sdManager.removeEventListener(SocketConnectionEvent.SOCKET_DATA, onSocketData);
			sdManager.addEventListener(SocketConnectionEvent.SOCKET_FAULT_DATA, onFaultData);
			sdManager.removeEventListener(SocketConnectionEvent.SOCKET_ERROR, onConnError);
			
			if (sdManager.connected) sdManager.disconnect();
		}
		
		public function tryConnect(connVO:MessagingConnectVO):void {
			connectionVO = connVO;
			
			if (!sdManager.connected) sdManager.initialize(connVO.server, Number(connVO.port));
		}
		
		public function disconnect():void {
			if (sdManager.connected) sdManager.disconnect();
		}
		
		public function get connected():Boolean {
			return sdManager && sdManager.connected;
		}
		
		protected function onConnect(evt:SocketConnectionEvent):void {
			logger.info('Socket connected');
			facade.sendNotification(this.proxyName + CONNECTION_SUCCESS);
		}
		
		protected function onDisconnect(evt:SocketConnectionEvent):void {
			logger.info('Socket disconnected');
			facade.sendNotification(this.proxyName + CONNECTION_CLOSED, 'Соединение закрыто');
		}
		
		protected function onSocketData(evt:SocketConnectionEvent):void {
			var data:ExtByteArray = evt.data as ExtByteArray;	
			onData(data);	
		}
		
		protected function onFaultData(evt:SocketConnectionEvent):void {
			logger.warn('Not valid socket bytes: ' + evt.data);
		}
		
		protected function onConnError(evt:SocketConnectionEvent):void {
			logger.error('Socket connection error: ' + evt.data);
			facade.sendNotification(this.proxyName + CONNECTION_ERROR, evt.data);
		}
		
		/******  invoke from child classes  ********/
		
		protected function sendData(data:ExtByteArray):void {
			sdManager.sendData(data);
		}
		
		protected function onData(data:ExtByteArray):void {
			logger.debug('onData: ' + data.toString());
		}
		
	}
}